//
// Created by Key-Box-Min on 25/05/2020.
//

#ifndef UNTITLED_LEXICALANALYSIS_H
#define UNTITLED_LEXICALANALYSIS_H

#include <set>
#include <list>
#include <map>
#include <string>
#include <vector>

using namespace std;

//id分配器=================================

template<typename T>
class IdFactory{
public:
    template<typename ...Args>
    int created(Args &&...args){
        contentMap[baseid] = new T(std::forward<Args>(args)...);
        return baseid++;
    }

    void deleted(int id){
        contentMap.erase(id);
    }

    T&& get(int id){
        return contentMap[id];
    }

private:
    int baseid = 0;
    map<int,T> contentMap;
};

//自动机===================================

//DFA-----------------------
typedef struct __DFA_LexicalStatus{
    int id;
    char key;
    int target;
} DFA_LexicalStatus;

//DFA 状态集
//using _DFA_Lexical = map<int,DFA_LexicalStatus>;

//NFA-----------------------

//固定字
using FixedWord = string;

enum NFA_LexicalItemType{
    FixedWord_Type, //固定字
    Lexical_Type,   //自动机
    Char_Type       //单字
};

//NFA 项
typedef struct __NFA_LexicalItem{
    NFA_LexicalItemType type;
    void* content = nullptr;
}NFA_LexicalItem;

//自动机 NFA
typedef struct __NFA_LexicalStatus{
    int id;             //自己的id
    NFA_LexicalItem key;//边
    int targetId;       //目标状态id
} NFA_LexicalStatus;
//NFA 状态集
//using _NFA_Lexical = map<int,NFA_LexicalStatus>;

//终结符================================

using Terminator = int;

//产生式================================

//产生式元素类型
enum GenerativeItemType{
    Terminator_Type,    //终结符
    Generative_Type,    //非终结符 //产生式
    Grammar_Type,       //非终结符 //文法
};
//产生式元素
typedef struct __GenerativeItem{
    GenerativeItemType type;
    void* content = nullptr;
}GenerativeItem;

//产生式
using Generative = int;
//using _Generative = vector<Generative>;

//文法====================================

typedef struct __Grammer{
    set<Terminator>     terminatorSet;      //终结符集
    set<Generative>     unTerminatorSet;    //非终结符集
    Generative          unTerminatorStart;  //开始符号
    set<Generative>     gererativeSet;      //产生式集
}Grammer;

#endif //UNTITLED_LEXICALANALYSIS_H

//    std::promise<int> pro;
//    auto fu = pro.get_future();
//    std::thread t([&](){
//        std::cout<<fu.get()<<std::endl;
//    });
//    pro.set_value(4);
//    t.join();
//
//    CThread<void ()> t([](){
//        std::cout<<"sss"<<std::endl;
//    });
//    t.start();
//    t.start();
//    t.start();
//    t.join();

//    for(auto p = map1.begin();p != map1.end();p++){
////        std::any& an = ;
////        std::cout<<an.type().name()<<std::endl;
//        if(an.type() == typeid(int))
//            std::cout<<std::any_cast<int>(an)<<std::endl;
//        else if(an.type() == typeid(char const *))
//            std::cout<<std::any_cast<char const *>(an)<<std::endl;
//        else if(an.type() == typeid(double))
//            std::cout<<std::any_cast<double >(an)<<std::endl;
//    }

//    std::list<std::any> list2;
//    list2.push_back(2);
//    list2.push_back("sss");
//    list2.push_back(3.1);
//
//    for(auto p = list2.begin();p != list2.end();p++){
//        std::any& an = *p;
////        std::cout<<an.type().name()<<std::endl;
//        if(an.type() == typeid(int))
//            std::cout<<std::any_cast<int>(an)<<std::endl;
//        else if(an.type() == typeid(char const *))
//            std::cout<<std::any_cast<char const *>(an)<<std::endl;
//        else if(an.type() == typeid(double))
//            std::cout<<std::any_cast<double >(an)<<std::endl;
//    }

//    AtomicList<std::string,int> list;
//
//    std::list<std::string> mmm;
//    std::string sss = "";
//    int c = 0;
//    AtomicLock lock;
//    EventQueue<int> queue1;
//
//    std::thread t1([&](){
//        for(int i=0;i<10;i++){
////            std::cout<<std::this_thread::get_id;
////            std::this_thread::sleep_for(std::chrono::milliseconds(100));
////            std::cout<<"A"<<std::endl;
//            queue1.push(i);
//        }
////        int n = 0;
////        while (queue1.pop(n))
////            std::cout<<n<<std::endl;
//    });
//    std::thread t2([&](){
//        for(int i=10;i<20;i++){
////            std::this_thread::sleep_for(std::chrono::milliseconds (100));
////            std::cout<<"B"<<std::endl;
//            queue1.push(i);
//        }
////        int n = 0;
////        while (queue1.pop(n))
////            std::cout<<n<<std::endl;
//    });
//
//    t1.join();
////    t2.join();
//
//    std::thread t3([&](){
//        for(int i=0;i<20;i++){
////            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//            std::cout<<"C"<<std::endl;
//            int n = 0;
//            if (queue1.pop(n))
//                std::cout<<n<<std::endl;
//        }
//    });
//    std::thread t4([&](){
//        for(int i=0;i<20;i++){
////            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//            std::cout<<"D"<<std::endl;
//            int n = 0;
//            if (queue1.pop(n))
//                std::cout<<n<<std::endl;
//        }
//    });
//    t3.join();
//    t4.join();
//
//    int n = 0;
//    while (queue1.pop(n))
//        std::cout<<n<<std::endl;
//    std::cout<<c<<std::endl;

//    std::cout<<cou<<std::endl;

//    list.push(1,33);
//    list.push(3,44);
//    list.push(3,443);
//
//    int a;
//    int b;
//    while(list.pop(a,b))
//        std::cout<<a<<" "<<b<<std::endl;

//    int b = 0;
//    std::list<std::string> a;
//    std::atomic_int  count = 0;
//    std::atomic_int be = 0;
//
//    AtomicLock lock;
//    std::thread t1([&](){
//        for(int i=0;i<1000;i++){
//            AtomicLock_guard l(&lock);
//            a.push_back("A");
//        }
//        be++;
//    });
//    std::thread t2([&](){
//        for(int i=0;i<1000;i++){
//            AtomicLock_guard l(&lock);
//            a.push_back("B");
//        }
//        be++;
//    });
//
//    std::thread t3([&](){
//        for(int i=0;i<2000;i++){
//            while (a.empty())continue;
//            AtomicLock_guard l(&lock);
//            a.pop_back();
//        }
//    });
//
//    t1.join();
//    t2.join();
//    t3.join();
//    std::cout<<a.size()<<"   "<<count<<std::endl;

//    MemoryPool<int> ll(3);
//
//    int* a = (int*)ll.get();
//    *a = 3;
//    std::cout<<a<<std::endl;

//MemoryPools<int> m(10,10);

//    p = (int*) MemoryPool<int>::pool<3>().get();

//    struct llf * vp = (struct llf*) MemoryPool<struct llf>::pool<2>().get();
//    int * p1 = (int*) MemoryPool<int>::pool<2>().get();
//    int * p2 = (int*) MemoryPool<int>::pool<2>().get();
//    p = (int*) MemoryPool<int>::pool<2>().get();
//    std::cout<<p<<std::endl;
//    p = (int*) MemoryPool<int>::pool<2>().get();
//    std::cout<<p<<std::endl;
//    p = (int*) MemoryPool<int>::pool<2>().get();
//    std::cout<<p<<std::endl;
//    p = (int*) MemoryPool<int>::pool<2>().get();
//    std::cout<<p<<std::endl;

//    std::cout<<MemoryPool<int>::pool<3>().memorysSize()<<std::endl;

//    MemoryPoolAbstract b;


//    El pp1(1);
//    El pp2(2);
//    El pp3(3);
//
//    Diverter<El&,int,void (*)(El&)> driver(
//            [&](El& context,const std::map<int,back>& map) -> back{
//                if(map.find(context.getId()) == map.end())return nullptr;
//                return map.at(context.getId());
//            });
//
//    driver.add(pp1.getId(),ff1);
//    driver.add(pp2.getId(),ff2);
//    driver.add(pp3.getId(),ff3);
//
//    back p = driver.analysis(pp1);
//    if(p != nullptr)p(pp1);
//    p = driver.analysis(pp2);
//    if(p != nullptr)p(pp2);
//    p = driver.analysis(pp3);
//    if(p != nullptr)p(pp3);


//    int* p = new int[4]{1,2,3,4};
//    int* e = p+1;
//
//    std::cout<<(p+1)->b<<std::endl;
//    delete[2] p;
//    std::cout<<(e)->b<<std::endl;


//    char* sss = "caaa";
//
//    set<int> endset;    //end set
//    endset.insert(1);
//    endset.insert(2);
//
//    map<char,int> keym; //end char map
//    keym['a'] = 0;
//    keym['b'] = 1;
//
//    //status_set
//    map<int,set<Item>> status;
//    status[0] = set<Item>();
//    status[1] = set<Item>();
//    status[2] = set<Item>();
//    status[0].insert(Item('a',1));
//
//    auto status_m = createMap(status);
//    auto status_m = new Array<MapArrayPtr<int,int>>(status.size());
//    for(int i=0;i<status_m->len;i++)
//        status_m->data[i] = createMap(status[i]);
//
//    std::cout<<"\tchar\tstatus\tschar\tnewstatus"<<std::endl;
//    int s = 0;
//    for(int i = 0; i< strlen(sss);i++){
//        std::cout<<"\t"<<sss[i]<<"\t"<<s<<"\t";
//
//        char c = sss[i];                                    //get char source
//
//        int k = keym[c];                               //get char id
//
//        s = status[s][k];                                    //get char to status
//
//        std::cout<<status[s][keym[sss[i]]]<<"\t"<<s<<std::endl;
//    }
//    if(endset.find(s) != endset.end()) {
//        std::cout << "parse ok" << std::endl;               //ok
//    }else{
//        std::cout<<"parse no" <<std::endl;                  //no
//    }
